<?php
/*
 * Plugin Name: OSS Upload
 * Version: 1.9
 * Description: Upload with Aliyun OSS, with modified OSS Wrapper and fully native image edit function support.
 * Plugin URI: https://www.xiaomac.com/2016121895.html
 * Author: Link
 * Author URI: https://www.xiaomac.com
 * License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * Text Domain: oss-upload
 * Domain Path: /lang
*/

function ouop($k, $v=null){
    $op = isset($GLOBALS['oss_upload_options']) ? $GLOBALS['oss_upload_options'] : $GLOBALS['oss_upload_options'] = get_option('ouop');
    return isset($op[$k]) ? (isset($v) ? $op[$k] == $v : $op[$k]) : '';
}

add_action('init', 'oss_upload_init', 1);
function oss_upload_init(){
    if(!ouop('oss', 1) || !ouop('oss_akey') || !ouop('oss_skey') || !ouop('oss_endpoint')) return;
    define('OSS_ACCESS_ID', ouop('oss_akey'));
    define('OSS_ACCESS_KEY', ouop('oss_skey'));
    define('OSS_ENDPOINT', ouop('oss_endpoint'));
    require_once('lib/OSSWrapper.php');
    if(ouop('oss_mode')){
        add_filter('the_title', 'oss_upload_title', 10, 2);
        add_filter('the_content', 'oss_upload_content');
        add_filter('begin_fetch_post_thumbnail_html', 'oss_upload_post_thumbnail');
        add_filter('end_fetch_post_thumbnail_html', 'oss_upload_post_thumbnail_remove');
    }else{
        add_filter('upload_dir', 'oss_upload_upload_dir');
    }
}

function oss_upload_title($title, $id){
    add_filter('upload_dir', 'oss_upload_upload_dir', 101);
    return $title;
}
function oss_upload_content($content){
    if(has_filter('upload_dir', 'oss_upload_upload_dir')) remove_filter('upload_dir', 'oss_upload_upload_dir', 101);
    return $content;
}

function oss_upload_post_thumbnail(){
    add_filter('upload_dir', 'oss_upload_upload_dir', 102);
}
function oss_upload_post_thumbnail_remove(){
    if(has_filter('upload_dir', 'oss_upload_upload_dir')) remove_filter('upload_dir', 'oss_upload_upload_dir', 102);
}

function oss_upload_upload_dir($param){
    if(!ouop('oss', 1)) return $param;
    if(ouop('oss_path')){
        $param['basedir'] = trim(ouop('oss_path'), '/');
        $param['path'] = $param['basedir'] . $param['subdir'];
    }
    if(ouop('oss_url')){
        $param['baseurl'] = trim(ouop('oss_url'), '/');
        $param['url'] = $param['baseurl'] . $param['subdir'];
    }
    return $param;
}

add_action('admin_init', 'oss_upload_admin_init', 1);
function oss_upload_admin_init() {
    load_plugin_textdomain('oss-upload', '', dirname(plugin_basename( __FILE__ )) . '/lang');
    $GLOBALS['oss_upload_data'] = get_plugin_data( __FILE__ );
    register_setting('oss_upload_admin_options_group', 'ouop');
    if(!ouop('oss', 1) || !ouop('oss_akey') || !ouop('oss_skey') || !ouop('oss_endpoint')) return;
    if(has_filter('upload_dir', 'oss_upload_upload_dir')) return;
    global $pagenow;
    $action = isset($_GET['action']) ? $_GET['action'] : (isset($_POST['action']) ? $_POST['action'] : '');
    if(in_array($action, array('upload-plugin', 'upload-theme'))) return;
    if($action_hooks = ouop('oss_action_hook')) $action_hook = explode(',', str_replace(' ', '', $action_hooks));
    if($page_hooks = ouop('oss_page_hook')) $page_hook = explode(',', str_replace(' ', '', $page_hooks));
    if(in_array($pagenow, array('post.php', 'post-new.php', 'upload.php', 'media.php', 'media-new.php'))
        || ($pagenow == 'admin-ajax.php' && !in_array($action, array('bp_avatar_upload')))
        || ($pagenow == 'options-general.php' && isset($_GET['page']) && in_array($_GET['page'], array('oss-upload')))
        || ($pagenow == 'async-upload.php' && $action == 'upload-attachment')
        || (!empty($action_hook) && !empty($action) && in_array($action, $action_hook))
        || (!empty($page_hook) && !empty($_GET['page']) && in_array($_GET['page'], $page_hook)) ){
        add_filter('upload_dir', 'oss_upload_upload_dir', 100, 1);
    }
}

add_filter('plugin_action_links_'.plugin_basename( __FILE__ ), 'oss_upload_settings_link');
function oss_upload_settings_link($links) {
    return array_merge(array(oss_upload_link('options-general.php?page=oss-upload', __('Settings'))), $links);
}

add_filter('wp_image_editors', 'oss_upload_image_editors');
function oss_upload_image_editors($arr) {
    if(!ouop('oss_editor', 1)) return $arr;
    $arr = array_diff($arr, array('WP_Image_Editor_GD'));
    array_unshift($arr, 'WP_Image_Editor_GD');
    return $arr;
}

function oss_upload_data($key){
    $data = $GLOBALS['oss_upload_data'];
    return isset($data) && is_array($data) && isset($data[$key]) ? $data[$key] : '';
}

function oss_upload_show_more($cols, $ret=false){
    static $header = array();
    $arr  = get_user_option('managesettings_page_oss-uploadcolumnshidden');
    $hide = (is_array($arr) && in_array($cols, $arr)) ? ' hidden' : '';
    $head = in_array($cols, $header) ? " class='{$cols}" : " id='{$cols}' class='manage-column";
    $out = "{$head} column-{$cols}{$hide}'";
    if(!in_array($cols, $header)) $header[] = $cols;
    if($ret) return $out;
    echo $out;
}

add_filter('manage_settings_page_oss-upload_columns', 'oss_upload_setting_columns');
function oss_upload_setting_columns($cols){
    $cols['_title'] = __('Show More','oss-upload');
    $cols['oss_upload_desc'] = __('Descriptions', 'oss-upload');
    $cols['oss_upload_example'] = __('Examples', 'oss-upload');
    return $cols;
}

function oss_upload_link($url, $text='', $ext=''){
    if(empty($text)) $text = $url;
    $button = stripos($ext, 'button') !== false ? " class='button'" : "";
    $target = stripos($ext, 'blank') !== false ? " target='_blank'" : "";
    $link = "<a href='{$url}'{$button}{$target}>{$text}</a>";
    return stripos($ext, 'p') !== false ? "<p>{$link}</p>" : "{$link} ";
}

add_filter('intermediate_image_sizes_advanced', 'oss_upload_intermediate', 9999);
function oss_upload_intermediate($sizes){
    if(ouop('oss_thumbnail', 1)) return array();
    return $sizes;
}

add_filter('wp_generate_attachment_metadata', 'oss_upload_generate_metadata', 9999);
function oss_upload_generate_metadata($data) {
    if(!empty($data['sizes']) && ouop('oss_thumbnail')>1){
        $dir = preg_match('/\//', dirname($data['file'])) ? '/'.dirname($data['file']) : '';
        $uploads = wp_upload_dir();
        foreach ($data['sizes'] as $s => $v){
            $file = $uploads['basedir'].$dir.'/'.$v['file'];
            if(@file_exists($file)) @unlink($file);
        }
    }
    return $data;
}

add_filter('wp_get_attachment_metadata', 'oss_upload_get_metadata', 9999);
function oss_upload_get_metadata($data) {
    if(!empty($data['sizes']) && ouop('oss_thumbnail')>1){
        foreach ($data['sizes'] as $s => $v){
            if(isset($v['file']) && preg_match('/x-oss-process/', $v['file'])) continue;
            if(ouop('oss_thumbnail', 2)){
                $data['sizes'][$s]['file'] = basename($data['file'])."?x-oss-process=image/resize,m_fill,w_{$v['width']},h_{$v['height']}";
            }
            if(ouop('oss_thumbnail', 3)){
                $data['sizes'][$s]['file'] = basename($data['file'])."?x-oss-process=style/{$s}";
            }
        }
    }
    return $data;
}

add_action('current_screen', 'oss_upload_setting_screen');
function oss_upload_setting_screen() {
    $screen = get_current_screen();
    if($screen->id != 'settings_page_oss-upload') return;
    $help_content = '<p>'.oss_upload_data('Description').'</p><br/>'.
        '<p>'.oss_upload_link('http://www.aliyun.com/product/oss/', 'Aliyun OSS', 'button,blank').
        oss_upload_link('https://oss.console.aliyun.com/index', 'OSS Console', 'button,blank').
        oss_upload_link('https://help.aliyun.com/document_detail/32174.html', 'PHP SDK', 'button,blank').
        oss_upload_link('https://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/internal/oss/0.0.4/assets/pdf/oss_sdk_php20150819.pdf', 'SDK PDF', 'button,blank').
        oss_upload_link('https://wordpress.org/plugins/oss-upload/', __('Plugin Rating', 'oss-upload'), 'button,blank').'</p>';
    $help_sidebar = '<p><strong>'.__('For more information', 'oss-upload').'</strong></p>'.
        oss_upload_link(oss_upload_data('PluginURI'), __('Support', 'oss-upload'), 'p,blank').
        oss_upload_link('https://www.xiaomac.com/about', __('Donote', 'oss-upload'), 'p,blank').
        oss_upload_link('https://www.xiaomac.com/tag/work', __('More Plugins', 'oss-upload'), 'p,blank');
    $screen->add_help_tab(array('id' => 'oss_upload_help', 'title' => __('About', 'oss-upload'), 'content' => $help_content));
    $screen->set_help_sidebar($help_sidebar);
}

add_action('admin_notices', 'oss_upload_admin_note');
function oss_upload_admin_note(){
    if(isset($_GET['settings-updated']) && $_GET['settings-updated']=='test'){
        try{
            $ok = false;
            $rnd = md5(time());
            $file = ouop('oss_path').'/oss_upload_'.$rnd.'.txt';
            $try = file_put_contents($file, $rnd);
            if($try == strlen($rnd)){
                $out = __('Write OK, ','oss-upload');
                $try = file_get_contents($file);
                if($try == $rnd){
                    $out .= __('Read OK, ', 'oss-upload');
                    $try = unlink($file);
                    if($try === true){
                        $out .= __('Delete OK', 'oss-upload');
                        $ok = true;
                    }else{
                        throw new RequestCore_Exception($out . __('Delete Error: ', 'oss-upload') . $try);
                    }
                }else{
                    throw new RequestCore_Exception($out . __('Read Error: ', 'oss-upload') . $try);
                }
            }else{
                throw new RequestCore_Exception($out . __('Write Error: ', 'oss-upload') . $try);
            }
        }catch(Exception $ex){
            $out = esc_html($ex->message);
        }
        echo '<div class="'. ($ok ? 'updated fade' : 'error') . '"><p>'.$out.'</p></div>';
    }
}

add_action('admin_menu', 'oss_upload_admin_menu');
function oss_upload_admin_menu() {
    add_options_page(__('OSS Upload','oss-upload'), __('OSS Upload','oss-upload'), 'manage_options', 'oss-upload', 'oss_upload_options_page');
}

function oss_upload_options_page(){?>
    <div class="wrap">
        <h2><?php _e('OSS Upload','oss-upload')?> <small><small><?php echo oss_upload_data('Version');?></small></small></h2>
        <form action="options.php" method="post">
        <?php settings_fields('oss_upload_admin_options_group'); ?>
        <table class="form-table">
        <tr valign="top">
        <th scope="row"><?php _e('Enable','oss-upload')?></th>
        <td>
            <label><input name="ouop[oss]" type="checkbox" value="1" <?php checked(ouop('oss'),1);?> />
            <?php _e('Use OSS as media library storage','oss-upload')?></label>
        </td></tr>
        <tr valign="top">
        <th scope="row"><?php _e('Access Key','oss-upload')?></th>
        <td>
            <input name="ouop[oss_akey]" size="60" placeholder="Access Key" value="<?php echo ouop('oss_akey')?>" required />
            <?php echo oss_upload_link('https://ak-console.aliyun.com/', '?', 'blank'); ?>
        </td></tr>
        <tr valign="top">
        <th scope="row"><?php _e('Secret Key','oss-upload')?></th>
        <td>
            <input name="ouop[oss_skey]" size="60" placeholder="Secret Key" value="<?php echo ouop('oss_skey')?>" required />
            <?php echo oss_upload_link('https://ak-console.aliyun.com/', '?', 'blank'); ?>
        </td></tr>
        <tr valign="top">
        <th scope="row"><?php _e('Upload Path','oss-upload')?></th>
        <td>
            <input name="ouop[oss_path]" size="60" placeholder="oss://{BUCKET}/{PATH}" value="<?php echo ouop('oss_path')?>" required />
            <?php echo oss_upload_link('https://help.aliyun.com/document_detail/31902.html', '?', 'blank'); ?>
            <p <?php oss_upload_show_more('oss_upload_desc'); ?>><small><?php _e('<code>{PATH}</code> can be empty, with no slash at the end','oss-upload')?></small></p>
            <div <?php oss_upload_show_more('oss_upload_example'); ?>>
            <p><small><code>oss://my-bucket</code></small></p>
            <p><small><code>oss://my-bucket/uploads</code></small></p>
            </div>
        </td></tr>
        <tr valign="top">
        <th scope="row"><?php _e('Visit URL','oss-upload')?></th>
        <td>
            <input name="ouop[oss_url]" size="60" placeholder="http://oss.aliyuncs.com/{BUCKET}/{PATH}" value="<?php echo ouop('oss_url')?>" required />
            <?php echo oss_upload_link('https://help.aliyun.com/document_detail/31902.html', '?', 'blank'); ?>
            <p <?php oss_upload_show_more('oss_upload_desc'); ?>><small><?php _e('<code>{PATH}</code> can be empty, <code>{BUCKET}</code> can be directory or domain, also can be https','oss-upload')?></small></p>
            <div <?php oss_upload_show_more('oss_upload_example'); ?>>
            <p><small><code>http://my-bucket.oss-cn-shenzhen.aliyuncs.com</code></small></p>
            <p><small><code>http://my-bucket.oss-cn-shenzhen.aliyuncs.com/uploads</code></small></p>
            <p><small><code>http://www.my-oss-domain.com</code></small></p>
            <p><small><code>http://www.my-oss-domain.com/uploads</code></small></p>
            </div>
        </td></tr>
        <tr valign="top">
        <th scope="row"><?php _e('Upload EndPoint','oss-upload')?></th>
        <td>
            <input name="ouop[oss_endpoint]" size="60" placeholder="oss-{cn-xxxxxx}.aliyuncs.com" value="<?php echo ouop('oss_endpoint')?>" required />
            <?php echo oss_upload_link('https://help.aliyun.com/document_detail/31837.html', '?', 'blank'); ?>
            <p <?php oss_upload_show_more('oss_upload_desc'); ?>><small><?php _e('<code>{BUCKET}</code> not included, default as <code>oss-cn-hangzhou.aliyuncs.com</code>','oss-upload')?></small></p>
            <div <?php oss_upload_show_more('oss_upload_example'); ?>>
            <p><small><code>oss-cn-shenzhen.aliyuncs.com</code></small></p>
            <p><small><code>oss-cn-shanghai.aliyuncs.com</code></small></p>
            <p><small><code>oss-us-west-1.aliyuncs.com</code></small></p>
            </div>
        </td></tr>
        <tr valign="top">
        <th scope="row"></th>
        <td>
            <?php 
            if(ouop('oss', 1) && ouop('oss_akey')){
                echo oss_upload_link('options-general.php?page=oss-upload&settings-updated=test', __('Run a test', 'oss-upload'), 'p,button');
            } ?>
        </td></tr>
        <tr valign="top">
        <th scope="row"><?php _e('Image Thumbnails','oss-upload')?></th>
        <td>
            <p><label><input name="ouop[oss_thumbnail]" type="radio" value="1" <?php checked(ouop('oss_thumbnail'),1);?> /> <?php _e('Disable thumbnails','oss-upload')?></label></p>
            <p <?php oss_upload_show_more('oss_upload_desc'); ?>><small><?php _e('Use origin image for display in all scenarios','oss-upload')?></small></p><br/>
            <p><label><input name="ouop[oss_thumbnail]" type="radio" value="0" <?php checked(ouop('oss_thumbnail1'),0);?> /> <?php _e('Generate thumbnails file in a violent way','oss-upload')?></label></p>
            <p <?php oss_upload_show_more('oss_upload_desc'); ?>><small><?php _e('Default but not recommended, which occupy lots of storage and mess up files structure','oss-upload')?></small></p>
            <p <?php oss_upload_show_more('oss_upload_example'); ?>><small><code>photo-{width}x{height}.jpg</code></small></p><br/>
            <p><label><input name="ouop[oss_thumbnail]" type="radio" value="2" <?php checked(ouop('oss_thumbnail'),2);?> /> <?php _e('Use OSS Image Service for a easy and simple way','oss-upload')?></label>
            <?php echo oss_upload_link('https://help.aliyun.com/document_detail/44688.html', '?', 'blank'); ?></p>
            <p <?php oss_upload_show_more('oss_upload_desc'); ?>><small><?php _e('Most recommended, which is compatible when you change your oss or thumbnails setting frequently','oss-upload')?></small></p>
            <p <?php oss_upload_show_more('oss_upload_example'); ?>><small><code>photo.jpg?x-oss-process=image/resize,m_fill,w_{width},h_{height}</code></small></p><br/>
            <p><label><input name="ouop[oss_thumbnail]" type="radio" value="3" <?php checked(ouop('oss_thumbnail'),3);?> /> <?php _e('Use OSS Image Service for a intelligent and complicated style way','oss-upload')?></label>
            <?php echo oss_upload_link('https://help.aliyun.com/document_detail/44687.html', '?', 'blank'); ?></p>
            <p <?php oss_upload_show_more('oss_upload_desc'); ?>><small><?php _e('Less recommended, which is more powerful but require more styles setting on your oss','oss-upload')?></small></p>
            <p <?php oss_upload_show_more('oss_upload_example'); ?>><small><code>photo.jpg?x-oss-process=style/{style}</code>: <code>thumbnail</code> <code>medium</code> <code>large</code> <code>medium_large</code> <code>post-thumbnail</code></small></p>
        </td></tr>
        <tr valign="top">
        <th scope="row"><?php _e('Image Editor Class', 'oss-upload')?></th>
        <td>
            <p><label><input name="ouop[oss_editor]" type="checkbox" value="1" <?php checked(ouop('oss_editor'),1);?> />
            <?php _e('Use <code>WP_Image_Editor_GD</code> as default','oss-upload')?></label></p>
            <p <?php oss_upload_show_more('oss_upload_desc'); ?>><small><?php _e('Which is more compatible and stable, check if error occurred when edit image','oss-upload')?></small></p>
        </td></tr>
        <tr valign="top">
        <th scope="row"><?php _e('Load Mode', 'oss-upload')?></th>
        <td>
            <p><label><input name="ouop[oss_mode]" type="checkbox" value="1" <?php checked(ouop('oss_mode'),1);?> />
            <?php _e('Use compatible mode instead of greedy mode','oss-upload')?></label></p>
            <p <?php oss_upload_show_more('oss_upload_desc'); ?>><small><?php _e('Check if there is compatible problem with other plugins','oss-upload')?></small></p>
        </td></tr>
        <tr valign="top">
        <th scope="row"><?php _e('Upload Hook','oss-upload')?></th>
        <td>
            <p><label><input name="ouop[oss_action_hook]" size="60" placeholder="$_GET['action']" value="<?php echo ouop('oss_action_hook')?>" /></label></p>
            <p><label><input name="ouop[oss_page_hook]" size="60" placeholder="$_GET['page']" value="<?php echo ouop('oss_page_hook')?>" /> </label></p>
            <p <?php oss_upload_show_more('oss_upload_desc'); ?>><small><?php _e('When <code>Load Mode</code> checked, some case might need to hook with OSS Upload through $_GET manually','oss-upload')?></small></p>
        </td></tr>
        </table>
        <?php submit_button();?>
    </div>
    <?php
}

?>